package com.xframework.security.controller;

import com.xframework.Base;
import com.xframework.exception.BusinessException;
import com.xframework.security.api.SecurityRpcService;
import com.xframework.security.api.WxRpcService;
import com.xframework.security.model.*;
import com.xframework.security.util.Constant;
import com.xframework.security.util.DigestUtil;
import com.xframework.security.util.JWTUtil;
import com.xframework.security.util.WxConstant;
import io.jsonwebtoken.Claims;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

@RestController
public class WxController {

    @DubboReference
    private WxRpcService wxRpcService;

    public WxController() {
        System.out.println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx WxControlle xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
    }

    @PostConstruct
    public void init() {

    }

    @RequestMapping(
            value = {"/wx/CheckSignature"},
            method = {RequestMethod.POST, RequestMethod.GET}
    )
    public void checkSignature(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 微信加密签名
        String signature = request.getParameter("signature");
        // 时间戳
        String timestamp = request.getParameter("timestamp");
        // 随机数
        String nonce = request.getParameter("nonce");
        // 随机字符串
        String echostr = request.getParameter("echostr");

        System.out.println(signature);
        System.out.println(timestamp);
        System.out.println(nonce);
        System.out.println(echostr);

        PrintWriter out = response.getWriter();
        // 通过检验signature对请求进行校验，若校验成功则原样返回echostr，表示接入成功，否则接入失败
        if (this.checkSignature(signature, timestamp, nonce)) {
            System.out.println("weixin check signature success ");
        }
        out.print(echostr);
        out.close();
    }

    @RequestMapping(value = {"/WxAuthorize"}, method = {RequestMethod.POST, RequestMethod.GET})
    public void authorize(String url, HttpServletRequest request, HttpServletResponse response) throws Exception {
        System.out.println("======================================" + url);
        String redirectUrl = WxConstant.wxDomainUrl + WxConstant.wxRedirectUrl + URLEncoder.encode("?url=" + url, StandardCharsets.UTF_8.name());
        response.setContentType("text/html");
        response.setCharacterEncoding(StandardCharsets.UTF_8.name());
        request.setCharacterEncoding(StandardCharsets.UTF_8.name());
        String wxRedirectUrl = MessageFormat.format(WxConstant.WX_AUTHORIZE_URL, WxConstant.wxAppId, redirectUrl);
        response.sendRedirect(wxRedirectUrl);
    }

    @RequestMapping(value = {"/WxToken"}, method = {RequestMethod.POST, RequestMethod.GET})
    public ModelAndView token(HttpServletRequest request) {
        String url = request.getParameter("url");
        System.out.println("=====token====11111111111111111===============" + url);
        Map<String, Object> wxWebAccessTokenMap = wxRpcService.getWxWebAccessToken(request);
        String openid = wxWebAccessTokenMap.get(WxConstant.OPENID).toString();
        System.out.println("===================openid===================" + openid);

        String accessToken = wxRpcService.getWxGlobalAccessToken();
        String jsApiTicket = wxRpcService.getWxJsApiTicket();

        Map<String, Object> userInfoMap = wxRpcService.getUserInfoByTokenOpenId(accessToken, openid);
        userInfoMap.put("userOpenId", openid);
        userInfoMap.put("userHeadImgUrl", userInfoMap.get("headimgurl"));
//        WxUser wxUser = new WxUser();
//        wxUser.setWxNickName((String) userInfoMap.get("nickname"));
//        wxUser.setWxSex((Integer) userInfoMap.get("sex"));
//        wxUser.setWxHeadImgUrl((String) userInfoMap.get("headimgurl"));
//        wxUser.setWxCountry((String) userInfoMap.get("country"));
//        wxUser.setWxProvince((String) userInfoMap.get("province"));
//        wxUser.setWxCity((String) userInfoMap.get("city"));
//        loginModelAndView = new ModelAndView("/controller/Login?applicationId=3&hasSession=true&loginUrl=/controller/getWxUserSession" + (redirectUrl == null ? "" : "?redirectUrl=" + redirectUrl) + "&logoutUrl=/wx/index.jsp&accountId=" + user.getAccountId() + "&accountName=" + user.getUserMobile() + "&wxOpenId=" + openid);
//        request.setAttribute("userWxOpenId", openid);
        ModelAndView modelAndView = new ModelAndView(url, userInfoMap);
        return modelAndView;
//        RespData<Map> respData = new RespData<Map>(1);
//        respData.setResult(userInfoMap);
//        return respData;
    }

//    @RequestMapping(
//            value = {"/wx/pay/notify"},
//            method = {RequestMethod.POST, RequestMethod.GET}
//    )
//    public ModelAndView payNotify(HttpServletRequest request, HttpServletResponse response) {
//        try {
//            Map map = request.getParameterMap();
//            System.out.println("==========================================--------------------============");
//            return loginView;
//        } catch (Exception e) {
//            throw new BusinessException("wx get token is wrong", e);
//        }
//    }

    /**
     * 验证签名
     *
     * @param signature
     * @param timestamp
     * @param nonce
     * @return
     */
    private boolean checkSignature(String signature, String timestamp, String nonce) {
        String[] arr = new String[]{Constant.securityJwtKey, timestamp, nonce};
        // 将token、timestamp、nonce三个参数进行字典序排序
        Arrays.sort(arr);
        StringBuilder content = new StringBuilder();
        for (int i = 0; i < arr.length; i++) {
            content.append(arr[i]);
        }
        String tmpStr = null;

        try {
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            // 将三个参数字符串拼接成一个字符串进行sha1加密
            byte[] digest = md.digest(content.toString().getBytes());
            tmpStr = DigestUtil.byteToStr(digest);
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 将sha1加密后的字符串可与signature对比，标识该请求来源于微信
        return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
    }

}
